package com.echat.messagesender.sender.sms.impl.baseutil;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendBatchSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendBatchSmsResponse;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.echat.messagesender.sender.constant.Constants;
import com.echat.messagesender.sender.sms.bean.AliSmsConfig;
import com.echat.messagesender.sender.util.JsonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.Map;

/**
 * Created by huangzhilin on 2017/11/27.
 */
public class AliSmsUtil {
    private static Logger logger = LoggerFactory.getLogger(AliSmsUtil.class);
    //产品名称:云通信短信API产品,开发者无需替换
    static final String PRODUCT = "Dysmsapi";
    //产品域名,开发者无需替换
    static final String DOMAIN = "dysmsapi.aliyuncs.com";
    static final String ENDPOINT_NAME = "cn-hangzhou";
    static final String REGION_ID = "cn-hangzhou";

    static {
        //设置超时时间-可自行调整
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");
    }

    private static IAcsClient getAcsClient(AliSmsConfig config)  {
        //初始化acsClient,暂不支持region化
        IClientProfile profile = DefaultProfile.getProfile(REGION_ID, config.getAccessKeyId(), config.getAccessKeySecret());
        try {
            DefaultProfile.addEndpoint(ENDPOINT_NAME, REGION_ID, PRODUCT, DOMAIN);
        } catch (ClientException e) {
            logger.error("Ali短信服务调用发生内部异常 AliSmsUtil::DefaultProfile.addEndpoint error!");
        }
        IAcsClient acsClient = new DefaultAcsClient(profile);
        return acsClient;
    }

    /**
     * 发送短信给单个用户
     *
     * @param to
     * @param templateId 短信模板id
     * @param params     模板占位符替换的参数值
     * @return
     * @throws Exception
     */
    public static boolean sendTemplateSMS(AliSmsConfig config, String to, String templateId, Map params)  {

        IAcsClient acsClient = getAcsClient(config);

        //组装请求对象-具体描述见控制台-文档部分内容
        SendSmsRequest request = new SendSmsRequest();
        //必填:待发送手机号
        request.setPhoneNumbers(to);
        //必填:短信签名-可在短信控制台中找到
        request.setSignName(Constants.SMS_SIGN_NAME);
        //必填:短信模板-可在短信控制台中找到
        request.setTemplateCode(templateId);
        //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
        request.setTemplateParam(JsonUtil.toJSON(params));

        //选填-上行短信扩展码(无特殊需求用户请忽略此字段)
        //request.setSmsUpExtendCode("90997");

        //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
        //request.setOutId("yourOutId");

        //hint 此处可能会抛出异常
        try {
            SendSmsResponse response = acsClient.getAcsResponse(request);
            if (response.getCode() != null && Constants.OK.equals(response.getCode())) {
                //发送成功
                return true;
            } else {
                logger.error("AliSmsUtil.sendTemplateSMS 发送失败，Code:" + response.getCode());
                return false;
            }
        } catch (Exception e) {
            logger.error("AliSmsUtil.sendTemplateSMS.error.", e);
            return false;
        }
    }

    /**
     * 【批量】发送短信
     * 【注意】批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式
     * @param tos
     * @param templateId 短信模板id
     * @param data       发送数据
     * @return
     * @throws Exception
     */
    public static boolean sendBatchTemplateSMS(AliSmsConfig config,String[] tos, String templateId, Map[] data){

        IAcsClient acsClient = getAcsClient(config);

        //组装请求对象-具体描述见控制台-文档部分内容
        // #https://help.aliyun.com/document_detail/66041.html?spm=a2c4g.11186623.6.560.ccimpu
        SendBatchSmsRequest request = new SendBatchSmsRequest();
        //使用post提交
        request.setMethod(MethodType.POST);
        //必填:待发送手机号
        request.setPhoneNumberJson(JsonUtil.listToJSON(Arrays.asList(tos)));
        //必填:短信签名-可在短信控制台中找到
        request.setSignNameJson(JsonUtil.listToJSON(Arrays.asList(new String[]{Constants.SMS_SIGN_NAME})));
        //必填:短信模板-可在短信控制台中找到
        request.setTemplateCode(templateId);
        //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
        request.setTemplateParamJson(JsonUtil.listToJSON(Arrays.asList(data)));

        //选填-上行短信扩展码(无特殊需求用户请忽略此字段)
        //request.setSmsUpExtendCode("90997");

        //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
        //request.setOutId("yourOutId");

        //hint 此处可能会抛出异常
        try {
            SendBatchSmsResponse response = acsClient.getAcsResponse(request);
            if (response.getCode() != null && Constants.OK.equals(response.getCode())) {
                //发送成功
                return true;
            } else {
                logger.error("AliSmsUtil.sendBatchTemplateSMS 发送失败，Code:" + response.getCode());
                return false;
            }
        } catch (Exception e) {
            logger.error("AliSmsUtil.sendBatchTemplateSMS.error.", e);
            return false;
        }
    }


}